package com.xctech.iot.mqtt.sdk.publish;

import com.xctech.iot.mqtt.sdk.core.MqttAbstractClient;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;

/**
 * <pre>
 * mqtt客户端
 * </pre>
 *
 * @author: feihu.liang
 * @since: 2024/4/11 14:36
 */
@Slf4j
@Component
public class MqttPublisher extends MqttAbstractClient {

    private MqttClient client;

    /**
     * <pre>
     * 连接Mqtt
     * </pre>
     *
     * @param
     * @return void
     */
    @Override
    public void connect() throws MqttException {
        client = new MqttClient(mqttConfig.getHostUrl(),
                mqttConfig.getClientId() + "_publisher_" + System.currentTimeMillis(), new MemoryPersistence());
        // 建立连接
        client.connect(getConnOptions());
        log.info("mqtt publisher client connect success");
    }


    /**
     * <pre>
     * 发送消息
     * </pre>
     *
     * @param topic 主题
     * @param qos   消息质量
     * @param msg   消息内容
     */
    public void sendMsg(String topic, Integer qos, String msg) {
        try {
            client.publish(topic, msg.getBytes(StandardCharsets.UTF_8), qos, false);
            log.info("send msg topic:{},qos:{},msg:{}", topic, qos, msg);
        } catch (Exception e) {
            log.error("publish msg topic={} qos={} msg={}, error=", topic, qos, msg, e);
        }
    }

    /**
     * <pre>
     * 发送消息
     * </pre>
     *
     * @param topic 主题
     * @param msg   消息内容
     */
    public void sendMsg(String topic, String msg) {
        this.sendMsg(topic, QOS, msg);
    }

    /**
     * <pre>
     * 发送消息
     * </pre>
     *
     * @param topic 主题
     * @param msg   消息内容
     */
    public void sendZeroMsg(String topic, String msg) {
        this.sendMsg(topic, 0, msg);
    }

    /**
     * <pre>
     * 是否连接
     * </pre>
     *
     * @return java.lang.Boolean
     */
    public Boolean isConnected() {
        return client != null && client.isConnected();
    }

    /**
     * <pre>
     * 重连
     * </pre>
     */
    public void reconnect() {
        try {
            this.connect();
        } catch (Exception e) {
            log.error("connect error=", e);
        }
    }

}
